1   /*
2    * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  package java.applet;
26  
27  import java.awt.*;
28  import java.awt.image.ColorModel;
29  import java.io.IOException;
30  import java.io.ObjectInputStream;
31  import java.net.URL;
32  import java.net.MalformedURLException;
33  import java.util.Hashtable;
34  import java.util.Locale;
35  import javax.accessibility.*;
36  
37  /**
38   * An applet is a small program that is intended not to be run on
39   * its own, but rather to be embedded inside another application.
40   * <p>
41   * The <code>Applet</code> class must be the superclass of any
42   * applet that is to be embedded in a Web page or viewed by the Java
43   * Applet Viewer. The <code>Applet</code> class provides a standard
44   * interface between applets and their environment.
45   *
46   * @author      Arthur van Hoff
47   * @author      Chris Warth
48   * @since       JDK1.0
49   */
50  public class Applet extends Panel {
51  
52      /**
53       * Constructs a new Applet.
54       * <p>
55       * Note: Many methods in <code>java.applet.Applet</code>
56       * may be invoked by the applet only after the applet is
57       * fully constructed; applet should avoid calling methods
58       * in <code>java.applet.Applet</code> in the constructor.
59       *
60       * @exception HeadlessException if GraphicsEnvironment.isHeadless()
61       * returns true.
62       * @see java.awt.GraphicsEnvironment#isHeadless
63       * @since 1.4
64       */
65      public Applet() throws HeadlessException {
66          if (GraphicsEnvironment.isHeadless()) {
67              throw new HeadlessException();
68          }
69      }
70  
71      /**
72       * Applets can be serialized but the following conventions MUST be followed:
73       *
74       * Before Serialization:
75       * An applet must be in STOPPED state.
76       *
77       * After Deserialization:
78       * The applet will be restored in STOPPED state (and most clients will
79       * likely move it into RUNNING state).
80       * The stub field will be restored by the reader.
81       */
82      transient private AppletStub stub;
83  
84      /* version ID for serialized form. */
85      private static final long serialVersionUID = -5836846270535785031L;
86  
87      /**
88       * Read an applet from an object input stream.
89       * @exception HeadlessException if
90       * <code>GraphicsEnvironment.isHeadless()</code> returns
91       * <code>true</code>
92       * @serial
93       * @see java.awt.GraphicsEnvironment#isHeadless
94       * @since 1.4
95       */
96      private void readObject(ObjectInputStream s)
97          throws ClassNotFoundException, IOException, HeadlessException {
98          if (GraphicsEnvironment.isHeadless()) {
99              throw new HeadlessException();
100         }
101         s.defaultReadObject();
102     }
103 
104     /**
105      * Sets this applet's stub. This is done automatically by the system.
106      * <p>If there is a security manager, its <code> checkPermission </code>
107      * method is called with the
108      * <code>AWTPermission("setAppletStub")</code>
109      * permission if a stub has already been set.
110      * @param   stub   the new stub.
111      * @exception SecurityException if the caller cannot set the stub
112      */
113     public final void setStub(AppletStub stub) {
114         if (this.stub != null) {
115             SecurityManager s = System.getSecurityManager();
116             if (s != null) {
117                 s.checkPermission(new AWTPermission("setAppletStub"));
118             }
119         }
120         this.stub = (AppletStub)stub;
121     }
122 
123     /**
124      * Determines if this applet is active. An applet is marked active
125      * just before its <code>start</code> method is called. It becomes
126      * inactive just before its <code>stop</code> method is called.
127      *
128      * @return  <code>true</code> if the applet is active;
129      *          <code>false</code> otherwise.
130      * @see     java.applet.Applet#start()
131      * @see     java.applet.Applet#stop()
132      */
133     public boolean isActive() {
134         if (stub != null) {
135             return stub.isActive();
136         } else {        // If stub field not filled in, applet never active
137             return false;
138         }
139     }
140 
141     /**
142      * Gets the URL of the document in which this applet is embedded.
143      * For example, suppose an applet is contained
144      * within the document:
145      * <blockquote><pre>
146      *    http://java.sun.com/products/jdk/1.2/index.html
147      * </pre></blockquote>
148      * The document base is:
149      * <blockquote><pre>
150      *    http://java.sun.com/products/jdk/1.2/index.html
151      * </pre></blockquote>
152      *
153      * @return  the {@link java.net.URL} of the document that contains this
154      *          applet.
155      * @see     java.applet.Applet#getCodeBase()
156      */
157     public URL getDocumentBase() {
158         return stub.getDocumentBase();
159     }
160 
161     /**
162      * Gets the base URL. This is the URL of the directory which contains this applet.
163      *
164      * @return  the base {@link java.net.URL} of
165      *          the directory which contains this applet.
166      * @see     java.applet.Applet#getDocumentBase()
167      */
168     public URL getCodeBase() {
169         return stub.getCodeBase();
170     }
171 
172     /**
173      * Returns the value of the named parameter in the HTML tag. For
174      * example, if this applet is specified as
175      * <blockquote><pre>
176      * &lt;applet code="Clock" width=50 height=50&gt;
177      * &lt;param name=Color value="blue"&gt;
178      * &lt;/applet&gt;
179      * </pre></blockquote>
180      * <p>
181      * then a call to <code>getParameter("Color")</code> returns the
182      * value <code>"blue"</code>.
183      * <p>
184      * The <code>name</code> argument is case insensitive.
185      *
186      * @param   name   a parameter name.
187      * @return  the value of the named parameter,
188      *          or <code>null</code> if not set.
189      */
190      public String getParameter(String name) {
191          return stub.getParameter(name);
192      }
193 
194     /**
195      * Determines this applet's context, which allows the applet to
196      * query and affect the environment in which it runs.
197      * <p>
198      * This environment of an applet represents the document that
199      * contains the applet.
200      *
201      * @return  the applet's context.
202      */
203     public AppletContext getAppletContext() {
204         return stub.getAppletContext();
205     }
206 
207     /**
208      * Requests that this applet be resized.
209      *
210      * @param   width    the new requested width for the applet.
211      * @param   height   the new requested height for the applet.
212      */
213     public void resize(int width, int height) {
214         Dimension d = size();
215         if ((d.width != width) || (d.height != height)) {
216             super.resize(width, height);
217             if (stub != null) {
218                 stub.appletResize(width, height);
219             }
220         }
221     }
222 
223     /**
224      * Requests that this applet be resized.
225      *
226      * @param   d   an object giving the new width and height.
227      */
228     public void resize(Dimension d) {
229         resize(d.width, d.height);
230     }
231 
232     /**
233      * Indicates if this container is a validate root.
234      * <p>
235      * {@code Applet} objects are the validate roots, and, therefore, they
236      * override this method to return {@code true}.
237      *
238      * @return {@code true}
239      * @since 1.7
240      * @see java.awt.Container#isValidateRoot
241      */
242     @Override
243     public boolean isValidateRoot() {
244         return true;
245     }
246 
247     /**
248      * Requests that the argument string be displayed in the
249      * "status window". Many browsers and applet viewers
250      * provide such a window, where the application can inform users of
251      * its current state.
252      *
253      * @param   msg   a string to display in the status window.
254      */
255     public void showStatus(String msg) {
256         getAppletContext().showStatus(msg);
257     }
258 
259     /**
260      * Returns an <code>Image</code> object that can then be painted on
261      * the screen. The <code>url</code> that is passed as an argument
262      * must specify an absolute URL.
263      * <p>
264      * This method always returns immediately, whether or not the image
265      * exists. When this applet attempts to draw the image on the screen,
266      * the data will be loaded. The graphics primitives that draw the
267      * image will incrementally paint on the screen.
268      *
269      * @param   url   an absolute URL giving the location of the image.
270      * @return  the image at the specified URL.
271      * @see     java.awt.Image
272      */
273     public Image getImage(URL url) {
274         return getAppletContext().getImage(url);
275     }
276 
277     /**
278      * Returns an <code>Image</code> object that can then be painted on
279      * the screen. The <code>url</code> argument must specify an absolute
280      * URL. The <code>name</code> argument is a specifier that is
281      * relative to the <code>url</code> argument.
282      * <p>
283      * This method always returns immediately, whether or not the image
284      * exists. When this applet attempts to draw the image on the screen,
285      * the data will be loaded. The graphics primitives that draw the
286      * image will incrementally paint on the screen.
287      *
288      * @param   url    an absolute URL giving the base location of the image.
289      * @param   name   the location of the image, relative to the
290      *                 <code>url</code> argument.
291      * @return  the image at the specified URL.
292      * @see     java.awt.Image
293      */
294     public Image getImage(URL url, String name) {
295         try {
296             return getImage(new URL(url, name));
297         } catch (MalformedURLException e) {
298             return null;
299         }
300     }
301 
302     /**
303      * Get an audio clip from the given URL.
304      *
305      * @param url points to the audio clip
306      * @return the audio clip at the specified URL.
307      *
308      * @since       1.2
309      */
310     public final static AudioClip newAudioClip(URL url) {
311         return new sun.applet.AppletAudioClip(url);
312     }
313 
314     /**
315      * Returns the <code>AudioClip</code> object specified by the
316      * <code>URL</code> argument.
317      * <p>
318      * This method always returns immediately, whether or not the audio
319      * clip exists. When this applet attempts to play the audio clip, the
320      * data will be loaded.
321      *
322      * @param   url  an absolute URL giving the location of the audio clip.
323      * @return  the audio clip at the specified URL.
324      * @see     java.applet.AudioClip
325      */
326     public AudioClip getAudioClip(URL url) {
327         return getAppletContext().getAudioClip(url);
328     }
329 
330     /**
331      * Returns the <code>AudioClip</code> object specified by the
332      * <code>URL</code> and <code>name</code> arguments.
333      * <p>
334      * This method always returns immediately, whether or not the audio
335      * clip exists. When this applet attempts to play the audio clip, the
336      * data will be loaded.
337      *
338      * @param   url    an absolute URL giving the base location of the
339      *                 audio clip.
340      * @param   name   the location of the audio clip, relative to the
341      *                 <code>url</code> argument.
342      * @return  the audio clip at the specified URL.
343      * @see     java.applet.AudioClip
344      */
345     public AudioClip getAudioClip(URL url, String name) {
346         try {
347             return getAudioClip(new URL(url, name));
348         } catch (MalformedURLException e) {
349             return null;
350         }
351     }
352 
353     /**
354      * Returns information about this applet. An applet should override
355      * this method to return a <code>String</code> containing information
356      * about the author, version, and copyright of the applet.
357      * <p>
358      * The implementation of this method provided by the
359      * <code>Applet</code> class returns <code>null</code>.
360      *
361      * @return  a string containing information about the author, version, and
362      *          copyright of the applet.
363      */
364     public String getAppletInfo() {
365         return null;
366     }
367 
368     /**
369      * Gets the locale of the applet. It allows the applet
370      * to maintain its own locale separated from the locale
371      * of the browser or appletviewer.
372      *
373      * @return  the locale of the applet; if no locale has
374      *          been set, the default locale is returned.
375      * @since   JDK1.1
376      */
377     public Locale getLocale() {
378       Locale locale = super.getLocale();
379       if (locale == null) {
380         return Locale.getDefault();
381       }
382       return locale;
383     }
384 
385     /**
386      * Returns information about the parameters that are understood by
387      * this applet. An applet should override this method to return an
388      * array of <code>Strings</code> describing these parameters.
389      * <p>
390      * Each element of the array should be a set of three
391      * <code>Strings</code> containing the name, the type, and a
392      * description. For example:
393      * <p><blockquote><pre>
394      * String pinfo[][] = {
395      *   {"fps",    "1-10",    "frames per second"},
396      *   {"repeat", "boolean", "repeat image loop"},
397      *   {"imgs",   "url",     "images directory"}
398      * };
399      * </pre></blockquote>
400      * <p>
401      * The implementation of this method provided by the
402      * <code>Applet</code> class returns <code>null</code>.
403      *
404      * @return  an array describing the parameters this applet looks for.
405      */
406     public String[][] getParameterInfo() {
407         return null;
408     }
409 
410     /**
411      * Plays the audio clip at the specified absolute URL. Nothing
412      * happens if the audio clip cannot be found.
413      *
414      * @param   url   an absolute URL giving the location of the audio clip.
415      */
416     public void play(URL url) {
417         AudioClip clip = getAudioClip(url);
418         if (clip != null) {
419             clip.play();
420         }
421     }
422 
423     /**
424      * Plays the audio clip given the URL and a specifier that is
425      * relative to it. Nothing happens if the audio clip cannot be found.
426      *
427      * @param   url    an absolute URL giving the base location of the
428      *                 audio clip.
429      * @param   name   the location of the audio clip, relative to the
430      *                 <code>url</code> argument.
431      */
432     public void play(URL url, String name) {
433         AudioClip clip = getAudioClip(url, name);
434         if (clip != null) {
435             clip.play();
436         }
437     }
438 
439     /**
440      * Called by the browser or applet viewer to inform
441      * this applet that it has been loaded into the system. It is always
442      * called before the first time that the <code>start</code> method is
443      * called.
444      * <p>
445      * A subclass of <code>Applet</code> should override this method if
446      * it has initialization to perform. For example, an applet with
447      * threads would use the <code>init</code> method to create the
448      * threads and the <code>destroy</code> method to kill them.
449      * <p>
450      * The implementation of this method provided by the
451      * <code>Applet</code> class does nothing.
452      *
453      * @see     java.applet.Applet#destroy()
454      * @see     java.applet.Applet#start()
455      * @see     java.applet.Applet#stop()
456      */
457     public void init() {
458     }
459 
460     /**
461      * Called by the browser or applet viewer to inform
462      * this applet that it should start its execution. It is called after
463      * the <code>init</code> method and each time the applet is revisited
464      * in a Web page.
465      * <p>
466      * A subclass of <code>Applet</code> should override this method if
467      * it has any operation that it wants to perform each time the Web
468      * page containing it is visited. For example, an applet with
469      * animation might want to use the <code>start</code> method to
470      * resume animation, and the <code>stop</code> method to suspend the
471      * animation.
472      * <p>
473      * Note: some methods, such as <code>getLocationOnScreen</code>, can only
474      * provide meaningful results if the applet is showing.  Because
475      * <code>isShowing</code> returns <code>false</code> when the applet's
476      * <code>start</code> is first called, methods requiring
477      * <code>isShowing</code> to return <code>true</code> should be called from
478      * a <code>ComponentListener</code>.
479      * <p>
480      * The implementation of this method provided by the
481      * <code>Applet</code> class does nothing.
482      *
483      * @see     java.applet.Applet#destroy()
484      * @see     java.applet.Applet#init()
485      * @see     java.applet.Applet#stop()
486      * @see     java.awt.Component#isShowing()
487      * @see     java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
488      */
489     public void start() {
490     }
491 
492     /**
493      * Called by the browser or applet viewer to inform
494      * this applet that it should stop its execution. It is called when
495      * the Web page that contains this applet has been replaced by
496      * another page, and also just before the applet is to be destroyed.
497      * <p>
498      * A subclass of <code>Applet</code> should override this method if
499      * it has any operation that it wants to perform each time the Web
500      * page containing it is no longer visible. For example, an applet
501      * with animation might want to use the <code>start</code> method to
502      * resume animation, and the <code>stop</code> method to suspend the
503      * animation.
504      * <p>
505      * The implementation of this method provided by the
506      * <code>Applet</code> class does nothing.
507      *
508      * @see     java.applet.Applet#destroy()
509      * @see     java.applet.Applet#init()
510      */
511     public void stop() {
512     }
513 
514     /**
515      * Called by the browser or applet viewer to inform
516      * this applet that it is being reclaimed and that it should destroy
517      * any resources that it has allocated. The <code>stop</code> method
518      * will always be called before <code>destroy</code>.
519      * <p>
520      * A subclass of <code>Applet</code> should override this method if
521      * it has any operation that it wants to perform before it is
522      * destroyed. For example, an applet with threads would use the
523      * <code>init</code> method to create the threads and the
524      * <code>destroy</code> method to kill them.
525      * <p>
526      * The implementation of this method provided by the
527      * <code>Applet</code> class does nothing.
528      *
529      * @see     java.applet.Applet#init()
530      * @see     java.applet.Applet#start()
531      * @see     java.applet.Applet#stop()
532      */
533     public void destroy() {
534     }
535 
536     //
537     // Accessibility support
538     //
539 
540     AccessibleContext accessibleContext = null;
541 
542     /**
543      * Gets the AccessibleContext associated with this Applet.
544      * For applets, the AccessibleContext takes the form of an
545      * AccessibleApplet.
546      * A new AccessibleApplet instance is created if necessary.
547      *
548      * @return an AccessibleApplet that serves as the
549      *         AccessibleContext of this Applet
550      * @since 1.3
551      */
552     public AccessibleContext getAccessibleContext() {
553         if (accessibleContext == null) {
554             accessibleContext = new AccessibleApplet();
555         }
556         return accessibleContext;
557     }
558 
559     /**
560      * This class implements accessibility support for the
561      * <code>Applet</code> class.  It provides an implementation of the
562      * Java Accessibility API appropriate to applet user-interface elements.
563      * @since 1.3
564      */
565     protected class AccessibleApplet extends AccessibleAWTPanel {
566 
567         private static final long serialVersionUID = 8127374778187708896L;
568 
569         /**
570          * Get the role of this object.
571          *
572          * @return an instance of AccessibleRole describing the role of the
573          * object
574          */
575         public AccessibleRole getAccessibleRole() {
576             return AccessibleRole.FRAME;
577         }
578 
579         /**
580          * Get the state of this object.
581          *
582          * @return an instance of AccessibleStateSet containing the current
583          * state set of the object
584          * @see AccessibleState
585          */
586         public AccessibleStateSet getAccessibleStateSet() {
587             AccessibleStateSet states = super.getAccessibleStateSet();
588             states.add(AccessibleState.ACTIVE);
589             return states;
590         }
591 
592     }
593 }